﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
using System.Collections;
using System.Configuration;
using Cn.Edwon.Web.Ac;
using log4net;
using System.Reflection;
using System.Xml;
using Cn.Edwon.Web.Validation;
using System.Text.RegularExpressions;

namespace Cn.Edwon.Web {
    public static class ClientHelper {
        public static ILog log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);

        #region 属性和配置项定义

        #region 网站的常用和基本属性
        public const string SESS_USER_KEY = "session_activeuser";
        public const string SESS_LOGIN_REFURL_KEY = "sess_login_ref_url";

        private static string _RootUrl;
        public static string RootUrl {
            set {}
            get { return _RootUrl; }
        }
        
        private static string _RootPath;
        public static string RootPath {
            set { }
            get { return _RootPath; }
        }

        private static string _HostUrl;
        public static string HostUrl {
            set { }
            get { return _HostUrl; }
        }


        #endregion

        #region web.config中定义的jedwon/webSupport/authentication节点的内容
        private static AcConfigParms _Ac;
        public static AcConfigParms Ac {
            set { _Ac = value; }
            get { return _Ac; }
        }
        #endregion

        #region web.config中定义的jedwon/webSupport/crud节点的内容
        private static Boolean _CrudEnable;
        public static Boolean CrudEnable {
            get { return _CrudEnable; }
        }

        private static String _CrudConfigUri;
        public static String CrudConfigUri {
            get { return _CrudConfigUri; }
        }
        #endregion

        #region web.config中定义的jedwon/webSupport/validation节点的内容
        private static String _VdOutputVar;
        public static String VdOutputVar {
            set { }
            get { return _VdOutputVar; }
        }
        
        private static Boolean _VdEnable;
        public static Boolean VdEnable {
            set { }
            get { return _VdEnable; }
        }
        private static string _VdClientHandler;
        public static string VdClientHandler {
            set { }
            get { return _VdClientHandler; }
        }
        private static string _VdFormListener;
        public static string VdFormListener {
            set { }
            get { return _VdFormListener; }
        }
        private static string _VdConfigUri;
        public static string VdConfigUri {
            set { }
            get { return _VdConfigUri; }
        }
        
        #endregion

        #endregion

        #region 初始化工作
        /// <summary>
        /// 初始化网站基础数据
        /// </summary>
        /// <param name="server"></param>
        /// <param name="request"></param>
        public static void Init(HttpServerUtility server,HttpRequest request) {
            //网站目录
            String _virtualDir = request.ApplicationPath;

            //获取网站的根物理路径
            _RootPath = server.MapPath(_virtualDir);
            _RootPath = _RootPath.Replace("\\", "/");
            //如果不是以/结尾,加上/
            if (_RootPath.LastIndexOf("/") != _RootPath.Length - 1) {
                _RootPath += "/";
            }
            log.Debug("Site Root Path:" + _RootPath);

            string _host = request.ServerVariables["HTTP_HOST"];
            log.Debug("Server Variables of HTTP_HOST:" + _host);
            string _fullUrl = request.Url.ToString();
            log.Debug("Full Url:" + _fullUrl);

            try {
                Regex reg = new Regex("([^:]+://)([^:|/]*):?([0-9]*)(.*)", RegexOptions.IgnoreCase);
                Match ms = reg.Match(_fullUrl);
                String _protocol = ms.Groups[1].Value;//主机地址之前的部分
                _HostUrl = _protocol + _host;
                log.Debug("Init host url : " + _HostUrl);
            } catch(Exception ex) {
                _HostUrl = "http://unknown.host";
                log.Error("Init host url failed:"+ex.Message);
            }

            //获取网站的根路径
            if(_virtualDir=="/")
                _RootUrl = _HostUrl + _virtualDir ;
            else
                _RootUrl = _HostUrl + _virtualDir + "/";
            log.Debug("Fixed Root Url : " + _RootUrl);

            //读取jedwon配置文件
            InitConfigurationSection(server);
        }
        /// <summary>
        /// 初始化AC的配置内容
        /// </summary>
        /// <param name="ht"></param>
        private static void InitAcConfiguration(Hashtable ht, HttpServerUtility server) {
            if (_Ac == null) {
                _Ac = new AcConfigParms();
            }
            _Ac.Type = typeof(AcImplEmpty);
            _Ac.Enable = (Boolean)ht["AcEnable"];
            if (_Ac.Enable) {
                String fullName = (String)ht["AcTypeName"];
                if (fullName != null && fullName.Length > 0) {
                    String typeName = fullName.Split(',')[0];
                    String assemblyFile = fullName.Split(',')[1];
                    try {
                        Assembly ass = Assembly.LoadFrom(_RootPath + "bin/" + assemblyFile + ".dll");
                        _Ac.Type = ass.GetType(typeName);
                        log.Debug("加载Ac类型:" + typeName);
                    } catch(Exception ex) {
                        log.Error("加载Ac程序集异常：" + ex.Message);
                        _Ac.Type = typeof(AcImplEmpty);
                        log.Debug("未能加载Ac类型:" + typeName + ",使用空AcImplEmpty");
                    }
                } else {
                    log.Debug("未找到AcTypeName定义");
                }
                try {
                    _Ac.ConfigUrl = server.MapPath((String)ht["AcConfigUrl"]);
                } catch {
                    _Ac.ConfigUrl = "";
                }
                _Ac.LoginUrl = (String)ht["AcLoginUrl"];
                _Ac.RedirectAfterLogin = (String)ht["RedirectAfterLogin"];
                _Ac.PowerLowUrl = (String)ht["AcPowerLowUrl"];

                if (!String.IsNullOrEmpty(_Ac.ConfigUrl)) {
                    XmlNamespaceManager xnm = new XmlNamespaceManager(new NameTable());
                    xnm.AddNamespace("ns", "urn:edwon-cn:configuration");
                    XmlDocument doc = new XmlDocument();
                    _Ac.PublicUrls = new List<String>();
                    try {
                        doc.Load(_Ac.ConfigUrl);
                        XmlNodeList nl = doc.SelectNodes("/ns:jedwon/ns:authentication/ns:public/ns:pattern", xnm);
                        if (nl != null) {
                            foreach (XmlNode node in nl) {
                                _Ac.PublicUrls.Add(node.Attributes["value"].Value);
                            }
                        }
                    } catch { }
                    _Ac.ActivedUrls = new List<String>();
                    try {
                        XmlNodeList nl = doc.SelectNodes("/ns:jedwon/ns:authentication/ns:actived/ns:pattern", xnm);
                        if (nl != null) {
                            foreach (XmlNode node in nl) {
                                _Ac.ActivedUrls.Add(node.Attributes["value"].Value);
                            }
                        }
                    } catch { }
                }
            } else {
                _Ac.ConfigUrl = "";
                _Ac.LoginUrl = "";
                _Ac.RedirectAfterLogin = "";
                _Ac.PowerLowUrl = "";
                _Ac.ActivedUrls = new List<String>();
            }
        }
        /// <summary>
        /// 初始化Validation的配置内容
        /// </summary>
        /// <param name="ht"></param>
        private static void InitValidationConfiguration(Hashtable ht, HttpServerUtility server) {
            _VdEnable = (Boolean)ht["VdEnable"];
            if (_VdEnable) {
                _VdClientHandler = (String)ht["VdClientHandler"];
                _VdFormListener = (String)ht["VdFormListener"];
                _VdOutputVar = (String)ht["VdOutputVar"];
                if (!String.IsNullOrEmpty(_VdOutputVar)) {
                    QuickValidator.OutputVarName = _VdOutputVar;
                }
                try {
                    _VdConfigUri = server.MapPath((String)ht["VdConfigUri"]);
                    QuickValidator.doc.Load(_VdConfigUri);
                } catch(Exception ex) {
                    log.Error("QuickValidator加载VdConfigUri数据时异常：" + ex.Message);
                    _VdConfigUri = "";
                    QuickValidator.doc.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><jedwon xmlns=\"urn:edwon-cn:configuration\"></jedwon>");
                }
            } else {
                log.Debug("未设置Validation");
                _VdClientHandler = "";
                _VdConfigUri = "";
                _VdFormListener = "";
                _VdOutputVar = "";
                QuickValidator.doc.LoadXml("<?xml version=\"1.0\" encoding=\"utf-8\"?><jedwon xmlns=\"urn:edwon-cn:configuration\"></jedwon>");
            }
        }
        /// <summary>
        /// 初始化Crud的配置内容
        /// </summary>
        /// <param name="ht"></param>
        private static void InitCrudConfiguration(Hashtable ht,HttpServerUtility server) {
            _CrudEnable = (Boolean)ht["CrudEnable"];
            if (_CrudEnable) {
                try {
                    _CrudConfigUri = server.MapPath((String)ht["CrudConfigUri"]);
                } catch {
                    _CrudConfigUri = "";
                }
            } else {
                _CrudConfigUri = "";
            }
        }
        /// <summary>
        /// 初始化webSupport的配置内容
        /// </summary>
        private static void InitConfigurationSection(HttpServerUtility server) {
            try {
                Hashtable ht = (Hashtable)ConfigurationManager.GetSection("jedwon/webSupport");
                if (ht == null) return;
                InitAcConfiguration(ht,server);
                InitValidationConfiguration(ht,server);
                InitCrudConfiguration(ht,server);
            } catch (Exception ex) {
                log.Error("读取节点jedwon/webSupport信息错误：" + ex.Message, ex);
            }
        }
        #endregion

        #region 其他方法
        /// <summary>
        /// 创建AC对象实体
        /// </summary>
        /// <returns></returns>
        public static IAuthentication CreateAc() {
            log.Debug("Create IAuthentication Entity("+_Ac.Type.ToString()+")");
            return (IAuthentication)Activator.CreateInstance(_Ac.Type);
        }
        /// <summary>
        /// 检查是否为公共页面，如果没有使用AC，则返回True
        /// </summary>
        /// <param name="rUrl">当前页面的Url</param>
        /// <returns></returns>
        public static Boolean IsPublicUrl(String rUrl) {
            if (!ClientHelper.Ac.Enable) return true;
            if (ClientHelper.Ac.PublicUrls == null
                || ClientHelper.Ac.PublicUrls.Count < 1) {
                    return false;
            }
            try {
                for (int i = 0; i < ClientHelper.Ac.PublicUrls.Count; i++) {
                    if (CheckUrl(ClientHelper.Ac.PublicUrls[i], rUrl))
                        return true;
                }
            } catch (Exception ex) {
                log.Error("Check Public Url Exception:" + ex.Message);
            }
            return false;
        }
        /// <summary>
        /// 检查是否只要登录就能通过的页面
        /// </summary>
        /// <param name="rUrl">当前页面的URL</param>
        /// <returns></returns>
        public static Boolean IsActivedUrl(String rUrl) {
            if (!ClientHelper.Ac.Enable) return true;
            if (ClientHelper.Ac.ActivedUrls == null
               || ClientHelper.Ac.ActivedUrls.Count < 1) {
                return false;
            } 
            try {
                for (int i = 0; i < ClientHelper.Ac.ActivedUrls.Count; i++) {
                    if (CheckUrl(ClientHelper.Ac.ActivedUrls[i], rUrl))
                        return true;
                }
            } catch (Exception ex) {
                log.Error("Check Actived Url Exception:" + ex.Message);
            }
            return false;
        }
        /// <summary>
        /// 检查页面是否符合Pattern的描述
        /// </summary>
        /// <param name="rPatternUrl"></param>
        /// <param name="rUrl">当前页面URL</param>
        /// <returns></returns>
        public static Boolean CheckUrl(String rPatternUrl, String rUrl) {
            if (String.IsNullOrEmpty(rUrl)) return false;
            String url = rUrl.ToLower();
            string pattern = rPatternUrl;
            pattern = pattern.Replace("//", "/");
            pattern = pattern.Replace("\\", "/");
            pattern = ClientHelper.RootUrl + pattern;
            pattern = pattern.ToLower();
            if (url.IndexOf(pattern) == 0) { //是其中的页面
                return true;
            }
            return false;
        }
        #endregion

        #region Util Methods
        /// <summary>
        /// 得到从网站根开始的资源uri，不包括get参数，不以/开始
        /// 通常用来作为资源的表示定义在配置文件中
        /// </summary>
        /// <param name="fullurl">当前访问页面的url</param>
        /// <returns></returns>
        public static String IdentyUri(String fullurl) {
            fullurl = fullurl.ToLower();
            fullurl = fullurl.Replace(ClientHelper.RootUrl.ToLower(), "");
            if (fullurl.IndexOf("?") != -1)
                return fullurl.Substring(0, fullurl.IndexOf("?"));
            else
                return fullurl;
        }
        /// <summary>
        /// 得到从网站根开始的资源uri，不包括get参数，不以/开始
        /// 通常用来作为资源的表示定义在配置文件中
        /// </summary>
        /// <param name="fullurl">当前访问页面的uri</param>
        /// <returns></returns>
        public static String IdentyUri(Uri uri) {
            String fullurl = uri.ToString();
            return IdentyUri(fullurl);
        }
        #endregion

        #region 控件相关
        /// <summary>
        /// 绑定一个ture/false的下拉列表
        /// </summary>
        /// <param name="ddl"></param>
        /// <param name="defaultValue"></param>
        /// <param name="trueText"></param>
        /// <param name="falseText"></param>
        public static void BindBoolean2Ddl(ref DropDownList ddl, Boolean defaultValue, string trueText, string falseText) {
            ddl.Items.Clear();
            if (defaultValue) {
                ddl.Items.Add(new ListItem(trueText, "1"));
                ddl.Items.Add(new ListItem(falseText, "0"));
            } else {
                ddl.Items.Add(new ListItem(falseText, "0"));
                ddl.Items.Add(new ListItem(trueText, "1"));
            }

        }
        /// <summary>
        /// 绑定一个ture/false的下拉列表，缺省使用内置的英文
        /// </summary>
        /// <param name="ddl"></param>
        /// <param name="defaultValue"></param>
        public static void BindBoolean2Ddl(ref DropDownList ddl, Boolean defaultValue) {
            BindBoolean2Ddl(ref ddl, defaultValue, "Yes", "No");
        }
        #endregion 
    }
}
